using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Collections.Specialized;
using System.Windows.Forms;

namespace AjGenesisStudio.Utils
{
    class ShellHelper
    {
        private static bool isClipboardCut = false;

        public static bool IsClipboardCut
        {
            get { return isClipboardCut; }
            set { isClipboardCut = value; }
        }
	

        #region copy
        public static bool CopyFiles(StringCollection source, StringCollection dest)
        {
            string[] arrSource = new string[source.Count];
            string[] arrDest = new string[dest.Count];
            source.CopyTo(arrSource, 0);
            dest.CopyTo(arrDest, 0);
            return CopyFiles(arrSource, arrDest);
        }

        public static bool CopyFiles(StringCollection source, string folder)
        {
            string[] arrSource = new string[source.Count];
            source.CopyTo(arrSource, 0);
            return CopyFiles(arrSource, folder);
        }

        public static bool CopyFiles(string source, string folder)
        {
            string[] arrSource = new string[0];
            arrSource[0] = source;
            return CopyFiles(arrSource, folder);
        }

        public static bool CopyFiles(string[] source, string[] dest)
        {
            ShellLib.ShellFileOperation fo = new ShellLib.ShellFileOperation();

            fo.Operation = ShellLib.ShellFileOperation.FileOperations.FO_COPY;
            fo.OwnerWindow = Global.Instance.MainForm.Handle;
            fo.SourceFiles = source;
            fo.DestFiles = dest;

            return fo.DoOperation();
        }

        public static bool CopyFiles(string[] source, string folder)
        {
            ShellLib.ShellFileOperation fo = new ShellLib.ShellFileOperation();

            fo.Operation = ShellLib.ShellFileOperation.FileOperations.FO_COPY;
            fo.OwnerWindow = Global.Instance.MainForm.Handle;
            fo.SourceFiles = source;

            string[] dest = new string[source.Length];
            for (int i = 0; i < source.Length; i++)
                dest[i] = Path.Combine(folder, Path.GetFileName(source[i]));

            fo.DestFiles = dest;

            return fo.DoOperation();
        }

        public static bool CopyClipboardFiles(string folder)
        {
            if (!Clipboard.ContainsFileDropList()) return false;

            StringCollection filePaths = Clipboard.GetFileDropList();
            string[] source = new string[filePaths.Count];
            filePaths.CopyTo(source, 0);
            string[] dest = new string[source.Length];

            ShellLib.ShellFileOperation fo = new ShellLib.ShellFileOperation();

            fo.Operation = ShellLib.ShellFileOperation.FileOperations.FO_COPY;
            fo.OwnerWindow = Global.Instance.MainForm.Handle;
            fo.SourceFiles = source;

            for (int i = 0; i < source.Length; i++)
                dest[i] = Path.Combine(folder, Path.GetFileName(source[i]));

            fo.DestFiles = dest;

            return fo.DoOperation();
        }
        #endregion

        #region move
        public static bool MoveFiles(StringCollection source, string folder)
        {
            string[] arrSource = new string[source.Count];
            source.CopyTo(arrSource, 0);
            return MoveFiles(arrSource, folder);
        }

        public static bool MoveFiles(StringCollection source, StringCollection dest)
        {
            string[] arrSource = new string[source.Count];
            string[] arrDest = new string[dest.Count];
            source.CopyTo(arrSource, 0);
            dest.CopyTo(arrDest, 0);
            return MoveFiles(arrSource, arrDest);
        }

        public static bool MoveFiles(string[] source, string[] dest)
        {
            ShellLib.ShellFileOperation fo = new ShellLib.ShellFileOperation();

            fo.Operation = ShellLib.ShellFileOperation.FileOperations.FO_MOVE;
            fo.OwnerWindow = Global.Instance.MainForm.Handle;
            fo.SourceFiles = source;
            fo.DestFiles = dest;

            return fo.DoOperation();
        }

        public static bool MoveFiles(string[] source, string folder)
        {
            ShellLib.ShellFileOperation fo = new ShellLib.ShellFileOperation();

            fo.Operation = ShellLib.ShellFileOperation.FileOperations.FO_MOVE;
            fo.OwnerWindow = Global.Instance.MainForm.Handle;
            fo.SourceFiles = source;

            string[] dest = new string[source.Length];
            for (int i = 0; i < source.Length; i++)
                dest[i] = Path.Combine(folder, Path.GetFileName(source[i]));

            fo.DestFiles = dest;

            return fo.DoOperation();
        }

        public static bool MoveClipboardFiles(string folder)
        {
            if (!Clipboard.ContainsFileDropList()) return false;

            StringCollection filePaths = Clipboard.GetFileDropList();
            string[] source = new string[filePaths.Count];
            filePaths.CopyTo(source, 0);
            
            ShellLib.ShellFileOperation fo = new ShellLib.ShellFileOperation();

            fo.Operation = ShellLib.ShellFileOperation.FileOperations.FO_MOVE;
            fo.OwnerWindow = Global.Instance.MainForm.Handle;
            fo.SourceFiles = source;

            string[] dest = new string[source.Length];
            for (int i = 0; i < source.Length; i++)
                dest[i] = Path.Combine(folder, Path.GetFileName(source[i]));

            fo.DestFiles = dest;

            return fo.DoOperation();
        }
        #endregion

        #region set clipboard
        public static void SetClipboardFiles(StringCollection source)
        {
            string[] arrSource = new string[source.Count];
            source.CopyTo(arrSource, 0);
            SetClipboardFiles(source);
        }

        public static void SetClipboardFiles(string[] files)
        {
            StringCollection filePaths = new StringCollection();
            filePaths.AddRange(files);

            Clipboard.SetFileDropList(filePaths);
        }

        public static void SetClipboardFiles(string files)
        {
            StringCollection filePaths = new StringCollection();
            filePaths.Add(files);

            Clipboard.SetFileDropList(filePaths);
        }
        #endregion

        #region delete
        public static bool Delete(string[] files)
        {
            bool res = true;
            
            ShellLib.ShellFileOperation fo = new ShellLib.ShellFileOperation();

            fo.Operation = ShellLib.ShellFileOperation.FileOperations.FO_DELETE;
            fo.OperationFlags &= ~ShellLib.ShellFileOperation.ShellFileOperationFlags.FOF_ALLOWUNDO;
            fo.OwnerWindow = Global.Instance.MainForm.Handle;
            fo.SourceFiles = files;

            fo.DoOperation();

            foreach (string f in files)
            {
                if (Directory.Exists(f) || File.Exists(f))
                {
                    res = false;
                    break;
                }
            }

            return res;
        }

        public static bool Delete(string folder)
        {
            ShellLib.ShellFileOperation fo = new ShellLib.ShellFileOperation();

            fo.Operation = ShellLib.ShellFileOperation.FileOperations.FO_DELETE;
            fo.OperationFlags &= ~ShellLib.ShellFileOperation.ShellFileOperationFlags.FOF_ALLOWUNDO;
            fo.OwnerWindow = Global.Instance.MainForm.Handle;
            string[] source = new string[1];
            source[0] = folder;
            fo.SourceFiles = source;

            fo.DoOperation();

            return !Directory.Exists(folder);
        }
        #endregion

        public static bool Open(string path)
        {
            ShellLib.ShellExecute shellExecute = new ShellLib.ShellExecute();
            shellExecute.Path = path;
            return shellExecute.Execute();
        }

        public static bool Rename(string filePath, string newName)
        {
            ShellLib.ShellFileOperation fo = new ShellLib.ShellFileOperation();

            fo.Operation = ShellLib.ShellFileOperation.FileOperations.FO_RENAME;
            fo.OwnerWindow = Global.Instance.MainForm.Handle;

            string[] source = new string[1];
            string[] dest = new string[1];

            source[0] = filePath;
            dest[0] = Path.Combine(Path.GetDirectoryName(filePath), newName);

            fo.SourceFiles = source;
            fo.DestFiles = dest;

            return fo.DoOperation();
        }
    }
}
